using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Windows;
using Phoenix.ActionResults;
using Phoenix.Framework;

namespace Phoenix
{
    public abstract class Controller : IController
    {
        internal void Initialise(ControllerActionContext controllerActionContext)
        {
            Context = controllerActionContext;
        }

        protected internal ControllerActionContext Context { get; private set; }

        protected PageActionResult Page()
        {
            return new PageActionResult(Context.ControllerAction.Action, new DefaultViewModel(), Context);
        }

        protected PageActionResult Page(ViewModelBase viewModel)
        {
            return new PageActionResult(Context.ControllerAction.Action, viewModel, Context);
        }

        protected DoNothingActionResult Nothing()
        {
            return new DoNothingActionResult(Context);
        }

        protected RedirectActionResult RedirectTo(string action, params object[] parameters)
        {
            if (!action.Contains("."))
                action = string.Format("{0}.{1}", Context.ControllerAction.Controller, action);
            var controllerAction = ControllerAction.CreateFrom(action, Context.ControllerAction.Assembly);
            return new RedirectActionResult(Context, controllerAction, parameters);
        }

        protected RedirectActionResult RedirectTo(Expression<Func<ActionResult>> action)
        {
            return new RedirectActionResult(Context, Context.ControllerAction.Controller, action);
        }

        protected RedirectActionResult RedirectTo(Expression<Func<Task<ActionResult>>> action)
        {
            return new RedirectActionResult(Context, Context.ControllerAction.Controller, action);
        }

        protected RedirectActionResult<TController> RedirectTo<TController>(Expression<Func<TController, ActionResult>> action) where TController : Controller
        {
            return new RedirectActionResult<TController>(Context, action);
        }

        protected RedirectActionResult RedirectTo(ControllerAction controllerAction)
        {
            return new RedirectActionResult(Context, controllerAction);
        }

        protected RedirectActionResult RedirectTo<TController>(string action) where TController : Controller
        {
            var controllerType = typeof(TController);
            var controllerAction = new ControllerAction(controllerType.Name, action, controllerType.Assembly.FullName);
            return new RedirectActionResult(Context, controllerAction);
        }

        protected NavigateBackActionResult Back()
        {
            return new NavigateBackActionResult(Context);
        }

        protected MessageBoxActionResult MessageBox(string messageBoxText, Action<MessageBoxCallback> resultCallback = null)
        {
            return new MessageBoxActionResult(Context, messageBoxText, resultCallback);
        }

        protected MessageBoxActionResult MessageBox(string messageBoxText, string caption, MessageBoxButton button, Action<MessageBoxCallback> resultCallback = null)
        {
            return new MessageBoxActionResult(Context, messageBoxText, caption, button, resultCallback);
        }

        protected ReturnResultActionResult Result(object result)
        {
            return new ReturnResultActionResult(Context, result);
        }

#if !WINDOWS_PHONE

        protected MessageBoxActionResult MessageBox(string messageBoxText, string caption, Action<MessageBoxCallback> resultCallback = null)
        {
            return new MessageBoxActionResult(Context, messageBoxText, caption, resultCallback);
        }

        protected MessageBoxActionResult MessageBox(
            string messageBoxText, string caption,
            MessageBoxButton button, MessageBoxImage icon,
            Action<MessageBoxCallback> resultCallback = null)
        {
            return new MessageBoxActionResult(Context, messageBoxText, caption, button, icon, resultCallback);
        }

        protected MessageBoxActionResult MessageBox(
            string messageBoxText, string caption,
            MessageBoxButton button, MessageBoxImage icon,
            MessageBoxResult defaultResult, Action<MessageBoxCallback> resultCallback = null)
        {
            return new MessageBoxActionResult(Context, messageBoxText, caption, button, icon, defaultResult, resultCallback);
        }

        protected MessageBoxActionResult MessageBox(
            string messageBoxText, string caption,
            MessageBoxButton button, MessageBoxImage icon, MessageBoxOptions options,
            MessageBoxResult defaultResult, Action<MessageBoxCallback> resultCallback = null)
        {
            return new MessageBoxActionResult(Context, messageBoxText, caption, button, icon, defaultResult, options, resultCallback);
        }

        protected WindowActionResult Window(bool modal = false)
        {
            return new WindowActionResult(Context.ControllerAction.Action, new DefaultViewModel(), Context, modal);
        }

        protected WindowActionResult Window(ViewModelBase viewModel, bool modal = false)
        {
            return new WindowActionResult(Context.ControllerAction.Action, viewModel, Context, modal);
        }
#endif
    }
}